function mxRubberband(graph)
{
	if (graph != null)
	{
		this.graph = graph;
		this.graph.addMouseListener(this);
		this.div = document.createElement('div');
		this.div.className = 'mxRubberband';
		mxUtils.setOpacity(this.div, this.defaultOpacity);

		mxEvent.redirectMouseEvents(this.div, this.graph);

		if (mxClient.IS_IE)
		{
			var self = this;
			mxEvent.addListener(window, 'unload', function()
			{
				self.destroy();
			});
		}
	}
};
mxRubberband.prototype.defaultOpacity = 20;
mxRubberband.prototype.enabled = true;
mxRubberband.prototype.isEnabled = function()
{
	return this.enabled;
};
mxRubberband.prototype.setEnabled = function(enabled)
{
	this.enabled = enabled;
};
mxRubberband.prototype.mouseDown = function(sender, me)
{
	if (!me.isConsumed() && this.isEnabled() && this.graph.isEnabled()
		&& (this.graph.isForceMarqueeEvent(me.getEvent()) || (me.getState() == null && me.getHandle() == null)))
	{
		this.start(me.getX(), me.getY());
		me.consume();
	}
	else
	{
		this.active = false;
	}
};
mxRubberband.prototype.start = function(x, y)
{
	var offset = mxUtils.getOffset(this.graph.container);
	var origin = mxUtils.getScrollOrigin(this.graph.container);
	origin.x -= offset.x;
	origin.y -= offset.y;
	this.startX = x + origin.x;
	this.startY = y + origin.y;
	this.redraw(x, y);
	this.div.style.visibility = 'visible';
	this.graph.container.appendChild(this.div);
	this.active = true;
};
mxRubberband.prototype.mouseMove = function(sender, me)
{
	if (this.active)
	{
		this.redraw(me.getX(), me.getY());
		me.consume();
	}
};
mxRubberband.prototype.mouseUp = function(sender, me)
{
	if (this.active)
	{
		this.reset();
		var rect = new mxRectangle(this.x, this.y, this.width, this.height);

		if (rect.width > this.graph.tolerance || rect.height > this.graph.tolerance)
		{
			this.graph.selectRegion(rect, me.getEvent());
			me.consume();
		}
	}
};
mxRubberband.prototype.reset = function()
{
	if (mxClient.FADE_RUBBERBAND)
	{
		mxUtils.fadeOut(this.div, 30, true, 10, null, mxClient.FADE_RUBBERBAND);
	}
	else
	{
		this.div.parentNode.removeChild(this.div);
	}
	this.active = false;
};
mxRubberband.prototype.redraw = function(x, y)
{
	var origin = mxUtils.getScrollOrigin(this.graph.container);
	var offset = mxUtils.getOffset(this.graph.container);
	origin.x -= offset.x;
	origin.y -= offset.y;
	x += origin.x;
	y += origin.y;
	this.x = Math.min(this.startX, x);
	this.y = Math.min(this.startY, y);
	this.width = Math.max(this.startX, x) - this.x;
	this.height = Math.max(this.startY, y) - this.y;
	this.div.style.left = this.x + 'px';
	this.div.style.top = this.y + 'px';
	this.div.style.width = Math.max(1, this.width) + 'px';
	this.div.style.height = Math.max(1, this.height) + 'px';
};
mxRubberband.prototype.destroy = function()
{
	if (!this.destroyed)
	{
		this.destroyed = true;
		this.graph.removeMouseListener(this);
		mxEvent.release(this.div);

		if (this.div.parentNode != null)
		{
			this.div.parentNode.removeChild(this.div);
		}
		this.div = null;
	}
};